package com.asj.vivo.lock.mq;

import static com.asj.enums.HttpRequestDictEnums.receiveMQMessageUrl;
import static com.asj.enums.MQDictEnums.executionEndpoint;
import static com.asj.enums.MQDictEnums.mdmFlag;
import static com.asj.enums.MQDictEnums.operatingMsgType;
import static com.asj.enums.MQDictEnums.queuePrefixName;
import static com.asj.enums.MQDictEnums.recording;
import static com.asj.enums.MQDictEnums.redelivered;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;

import com.asj.R;
import com.asj.config.RabbitMQHelper;
import com.asj.service.command.CommandReceptionUpdateService;
import com.asj.service.oppoSdk.OPPOSDKService;
import com.asj.service.request.RequestMDMService;
import com.asj.utils.CommonsUtils;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;


/**
 * MQ接收消息工具类
 * */
public class ReceiveMessageTask extends Service  {

    //设备客户端管理
    @SuppressLint("StaticFieldLeak")
    private static Context receiveMessageMQContext; // 用于持有 MainActivity 的引用
    private static final int NOTIFICATION_ID = 2;


    @Override
    public void onCreate() {
        super.onCreate();
        try{
            createNotification();
            new Thread(this::startReceivingMessages).start();
        }catch (Exception e){
            Log.e("创建MQ后台服务通知异常：：", Objects.requireNonNull(e.getMessage()));
        }
    }

    /**
     * 启动MQ服务
     * */
    public static void startMQService(Context... context){
        Context opContext;
        if(context == null || context.length == 0){
            opContext = ReceiveMessageTask.receiveMessageMQContext;
        }else{
            ReceiveMessageTask.receiveMessageMQContext = context[0];
            opContext = context[0];
        }
        Log.w("常驻服务 MainActivityService","startMQService");
        Intent intent = new Intent(opContext, ReceiveMessageTask.class);
        opContext.startForegroundService(intent);
    }

    /**
     * 摧毁MQ服务
     * */
    public static void stopMQService(Context... context){
        Context opContext;
        if(context == null || context.length == 0){
            opContext = ReceiveMessageTask.receiveMessageMQContext;
        }else{
            ReceiveMessageTask.receiveMessageMQContext = context[0];
            opContext = context[0];
        }
        Log.w("常驻服务 MainActivityService","stopMQService");
        opContext.stopService(new Intent(opContext, ReceiveMessageTask.class));
    }

    /**
     * 创建前台服务通知
     * */
    public void createNotification(){
        // 创建一个通知渠道，这是Android 8.0及以上版本要求的
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        String channelId = "child_custody_MQ_id";
        NotificationChannel channel = new NotificationChannel(
                channelId,
                "child_custody_MQ",
                NotificationManager.IMPORTANCE_MIN // 静默且无图标
        );
        channel.setShowBadge(false); // 禁用角标
        channel.enableLights(false); // 关闭指示灯
        channel.enableVibration(false); // 关闭震动
        channel.setSound(null, null); // 关闭声音
        notificationManager.createNotificationChannel(channel);

        /*CharSequence name = "child_custody_MQ";
        String description = "MQ监管服务";
        //IMPORTANCE_NONE 不会有通知显示以及声音提示
        int importance = NotificationManager.IMPORTANCE_NONE;
        NotificationChannel channel = new NotificationChannel("child_custody_MQ_id", name, importance);
        channel.setDescription(description);
        notificationManager.createNotificationChannel(channel);*/

        // 创建通知
        Notification notification = new NotificationCompat.Builder(this, "child_custody_MQ_id")
                .setContentTitle("指令监听中")
//                .setContentText("")
//                .setSmallIcon(R.drawable.transparent_icon)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setOngoing(true)
                .build();
        // 启动前台服务
        startForeground(NOTIFICATION_ID, notification);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    /**
     * MQ服务监听启动
     * */
    protected void startReceivingMessages() {
        RabbitMQHelper helper = new RabbitMQHelper();
        ConnectionFactory factory = helper.getConnectionFactory();
        try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
            //设置队列名称，指定aisheji.middleground.android.queue + 设备IMEI码
            String queueName = queuePrefixName.getName() + CommonsUtils.getDeviceCode(new OPPOSDKService(receiveMessageMQContext).getIMEI());

            // 声明队列
            channel.queueDeclare(queueName, true, false, false, null);

            // 定义消费者
            channel.basicConsume(queueName, false, new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                    Log.w("MQ监听服务启动！","MQ常驻监听服务启动！");

                    String message = new String(body, StandardCharsets.UTF_8);
                    System.out.println(" [x] Received '" + message + "'");
                    JsonObject json = JsonParser.parseString(message).getAsJsonObject();
                    try {
                        // 在这里，可以添加处理消息的代码
                        CommandReceptionUpdateService.getInstance(receiveMessageMQContext).onProgressUpdate(message);
                        //通过https发送给mdm告知处理结果 ,添加 flag 字段，并设置值为 "false"
                        json.addProperty(mdmFlag.getName(), "true");
                        json.addProperty(recording.getName(), "消费成功");
                        json.addProperty(operatingMsgType.getName(), "1");
                        json.addProperty(executionEndpoint.getName(), "2");
                        try {
                            String responseMsg = RequestMDMService.sendResult(json.toString(), receiveMQMessageUrl.getValue());
                            if (!responseMsg.isEmpty() && JsonParser.parseString(responseMsg).getAsJsonObject().get("code").getAsInt() == 200) {
                                System.out.println("mq执行告知成功！");
                            } else {
                                System.out.println("mq执行告知失败！");
                            }
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                        // 手动确认消息
                        channel.basicAck(envelope.getDeliveryTag(), false);

                    } catch (Exception e) {
                        //消息重试
                        if (json.has(redelivered.getName())) {
                            int redeliveredNumber = json.get(redelivered.getName()).getAsInt();
                            //判断是否要重新消费
                            //只重新消费三次
                            if (redeliveredNumber >= 0 && redeliveredNumber < 3) {
                                redeliveredNumber = redeliveredNumber + 1;
                                //通过https发送给mdm告知处理结果
                                int finalRedelivered = redeliveredNumber;
                                new Thread(() -> {
                                    //发送消息
                                    // 添加 flag 字段，并设置值为 "false"
                                    json.addProperty(redelivered.getName(), finalRedelivered);
                                    //要重新发送
                                    json.addProperty(mdmFlag.getName(), "false");
                                    json.addProperty(redelivered.getName(), finalRedelivered);
                                    json.addProperty(recording.getName(), "消息消费失败,重试消费中！");
                                    json.addProperty(operatingMsgType.getName(), "2");
                                    json.addProperty(executionEndpoint.getName(), "2");
                                    String responseMsg = null;
                                    try {
                                        responseMsg = RequestMDMService.sendResult(json.toString(), receiveMQMessageUrl.getValue());
                                    } catch (IOException ex) {
                                        throw new RuntimeException(ex);
                                    }
                                    if (!responseMsg.isEmpty() && JsonParser.parseString(responseMsg).getAsJsonObject().get("code").getAsInt() == 200) {
                                        System.out.println("mq执行告知成功！");
                                    } else {
                                        System.out.println("mq执行告知失败！");
                                    }
                                }).start();

                                //                                new SendMessageTask().execute(json.toString());
                                //确认消息已经被处理
                                channel.basicAck(envelope.getDeliveryTag(), false);
                            } else {
                                int finalRedelivered1 = redeliveredNumber;
                                new Thread(() -> {
                                    //发送消息
                                    // 添加 flag 字段，并设置值为 "false"
                                    json.addProperty(redelivered.getName(), finalRedelivered1);
                                    //要重新发送
                                    json.addProperty(mdmFlag.getName(), "false");
                                    json.addProperty(recording.getName(), "消息消费失败,重试消费因重试次数达到最大次数！");
                                    json.addProperty(operatingMsgType.getName(), "3");
                                    json.addProperty(executionEndpoint.getName(), "2");
                                    String responseMsg = null;
                                    try {
                                        responseMsg = RequestMDMService.sendResult(json.toString(), receiveMQMessageUrl.getValue());
                                    } catch (IOException ex) {
                                        throw new RuntimeException(ex);
                                    }
                                    if (!responseMsg.isEmpty() && JsonParser.parseString(responseMsg).getAsJsonObject().get("code").getAsInt() == 200) {
                                        System.out.println("mq执行告知成功！");
                                    } else {
                                        System.out.println("mq执行告知失败！");
                                    }
                                }).start();
                                //new SendMessageTask().execute(json.toString());
                                //超过最大次数就不重新加入消息队列了
                                channel.basicNack(envelope.getDeliveryTag(), false, false);
                            }
                        } else {
                            new Thread(() -> {
                                //发送消息
                                // 添加 flag 字段，并设置值为 "false"
                                //要重新发送
                                json.addProperty(mdmFlag.getName(), "false");
                                json.addProperty(recording.getName(), "消息消费失败,重试消费因重试次数消费为空被拒绝!");
                                json.addProperty(operatingMsgType.getName(), "3");
                                json.addProperty(executionEndpoint.getName(), "2");
                                String responseMsg = null;
                                try {
                                    responseMsg = RequestMDMService.sendResult(json.toString(), receiveMQMessageUrl.getValue());
                                } catch (IOException ex) {
                                    throw new RuntimeException(ex);
                                }
                                if (!responseMsg.isEmpty() && JsonParser.parseString(responseMsg).getAsJsonObject().get("code").getAsInt() == 200) {
                                    System.out.println("mq执行告知成功！");
                                } else {
                                    System.out.println("mq执行告知失败！");
                                }
                            }).start();
                            // new SendMessageTask().execute(json.toString());
                            // 拒绝消息，不重新排队
                            channel.basicNack(envelope.getDeliveryTag(), false, false);
                        }
                    }
                }
            });
            synchronized (this) {
                this.wait();
            }
        }catch (Exception e) {
            Log.e("启动MQ服务异常！", String.valueOf(e));
        }
    }

}
